package java_concurrency_explain_profound_in_simple.lock.reentrant_lock;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lixiangke
 * @date 2017/12/7
 */
public class AtomicIntegerWithLock {
    private Lock lock = new ReentrantLock();
    private int value;

    public AtomicIntegerWithLock(int value) {
        this.value = value;
    }

    public final int get() {
        try {
            lock.lock();
            return value;
        } finally {
            lock.unlock();
        }
    }

    public void set(int newValue) {
        try {
            lock.lock();
            this.value = newValue;
        } finally {
            lock.unlock();
        }
    }

    public final int getAndSet(int newValue) {
        try {
            lock.lock();
            int ret = this.value;
            this.value = newValue;
            return ret;
        } finally {
            lock.unlock();
        }
    }

    public boolean compareAndSet(int expect, int newValue) {
        try {
            lock.lock();
            if (expect == value) {
                this.value = newValue;
                return true;
            }
            return false;
        } finally {
            lock.unlock();
        }
    }

    public final int getAndIncrement() {
        lock.lock();
        try {
            return value++;
        } finally {
            lock.unlock();
        }
    }

    public final int getAndDecrement() {
        lock.lock();
        try {
            return value--;
        } finally {
            lock.unlock();
        }
    }

    public final int incrementAndGet() {
        lock.lock();
        try {
            return ++value;
        } finally {
            lock.unlock();
        }
    }

    public final int decrementAndGet() {
        lock.lock();
        try {
            return --value;
        } finally {
            lock.unlock();
        }
    }

    public String toString() {
        return Integer.toString(get());
    }


}
